package com.vben.common.exception.handler;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.hutool.core.bean.BeanUtil;
import com.vben.common.core.util.R;
import com.vben.common.exception.base.BaseException;
import com.vben.common.exception.enums.ErrorCode;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.resource.NoResourceFoundException;

/**
 * 全局异常处理器
 *
 * @author sunnfun
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    /**
     * 请求方式不支持
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public R<String> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,
                                                         HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
        return R.failed(e.getMessage());
    }

    /**
     * 业务异常
     */
    @ExceptionHandler(BaseException.class)
    public R<String> handleServiceException(BaseException e, HttpServletRequest request) {
        log.error(e.getMessage(), e);
        ErrorCode errorCode = e.getErrorCode();
        if (BeanUtil.isNotEmpty(errorCode)) {
            int code = errorCode.getCode();
            return code == 0 ? R.failed(e.getMessage()) : R.failed(code, e.getMessage());
        }
        return R.failed(e.getMessage());
    }

    /**
     * 未登陆异常
     */
    @ExceptionHandler(NotLoginException.class)
    public R<String> handleNotLoginException(NotLoginException e) {
        log.error(e.getMessage(), e);
        return R.failed(ErrorCode.NOT_LOGIN.getCode(), ErrorCode.NOT_LOGIN.getMessage());
    }

    /**
     * 资源不存在异常
     */
    @ExceptionHandler(NoResourceFoundException.class)
    public R<String> handleNoResourceFoundException(NoResourceFoundException e) {
        log.error(e.getMessage(), e);
        return R.failed(ErrorCode.RESOURCE_NOT_FOUND.getCode(), ErrorCode.RESOURCE_NOT_FOUND.getMessage());
    }

    /**
     * 无权限异常
     */
    @ExceptionHandler(NotRoleException.class)
    public R<String> handleNoResourceFoundException(NotRoleException e) {
        log.error(e.getMessage(), e);
        return R.failed(ErrorCode.NOT_ROLE.getCode(), ErrorCode.NOT_ROLE.getMessage());
    }

    /**
     * 系统异常
     */
    @ExceptionHandler(Exception.class)
    public R<String> handleException(Exception e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生系统异常.", requestURI, e);
        return R.failed(ErrorCode.INTERNAL_ERROR.getMessage());
    }

}
